package com.insleton.admin.employee.dao;

import com.insleton.admin.employee.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Map;

/**
 * 在Spring Data JPA中，JpaRepository 接口允许你通过定义特定的方法名来执行数据库查询，而无需实际编写JPQL或SQL查询。这种特性被称为查询方法（Query Method）的命名约定（Naming Conventions）。
 *
 * 以下是JpaRepository接口方法命名规则的一些关键点：
 *
 * 基本CRUD操作：
 * save(S entity): 保存一个实体。
 * findAll(): 查找所有实体。
 * findById(ID id): 根据ID查找一个实体。
 * existsById(ID id): 检查是否存在具有给定ID的实体。
 * count(): 计算实体的数量。
 * deleteById(ID id): 根据ID删除一个实体。
 * deleteAll(): 删除所有实体。
 * 查询方法命名约定：
 * 你可以通过在方法名中使用特定的关键字来定义查询。例如，findBy、getBy、readBy、countBy、existsBy等。
 * 接下来，你可以指定实体属性的名称。例如，如果你有一个名为User的实体，并且你想根据username属性查找用户，你可以定义一个名为findByUsername的方法。
 * 你可以使用And、Or来组合多个条件。例如，findByUsernameAndEmail。
 * 你可以使用Is、Equals、Not等来表示条件。但是，在大多数情况下，这些关键字是可选的，因为Spring Data JPA可以推断出你想要的意图。
 * 对于范围查询，你可以使用Between、GreaterThan、LessThan等关键字。例如，findByPriceBetween。
 * 对于排序和分页，你可以使用OrderBy和Pageable参数。例如，findByUsernameOrderByLastnameAsc(String username, Pageable pageable)。
 * 你可以使用Distinct来去除重复的结果。例如，findDistinctUsersByLastname(String lastname)。
 * 使用@Query注解：
 * 如果你发现命名约定不足以满足你的需求，或者你想使用更复杂的查询，你可以使用@Query注解来定义自定义的JPQL或SQL查询。
 * 例如：@Query("SELECT u FROM User u WHERE u.username = :username")。
 * 使用Specification接口：
 * 对于更复杂的查询，你还可以使用Specification接口来构建动态查询。
 * 总的来说，Spring Data JPA的查询方法命名约定提供了一种简洁且类型安全的方式来定义数据库查询，而无需编写大量的JPQL或SQL代码。但是，当需要更复杂的查询时，你也可以使用@Query注解或Specification接口来扩展你的功能。
 */
public interface EmployeeDao extends JpaRepository<Employee, String> {

    // 不管是命名参数，还是非命名参数，参数只能一个个的列出来。
    @Query("select u from Employee u where u.name = :name")
    List<Employee> queryList(@Param("name") String name);

    // 这个也是不可以的
    // @Query("select u from Employee u where u.name = :name")
    // List<Employee> queryListByMap(Map<String, Object> params);

    // 这种命名参数是不可以的，去掉@Param注解也不行的
    // Using named parameters for method public abstract java.util.List com.insleton.admin.employee.dao.EmployeeDao.queryListByBean(com.insleton.admin.employee.model.Employee) but parameter 'Optional[emp]' not found in annotated query 'select u from Employee u where u.name = :name'
    // @Query("select u from Employee u where u.name = :name")
    // List<Employee> queryListByBean(@Param("emp") Employee emp);

    @Query("select u from Employee u where u.name = ?1")
    List<Employee> queryBy(String name);
}
